UP | HOME

Implicit Rules of `make`

make 有一些隐含的(默认的)推导规则,掌握这些隐含规则不仅能帮我们简化 Makefile 的编写,也能避免我们写出的 Makefile 在 make 时出现奇怪的现象。

不过在此之前我们需要先了解一下 Makefile 当中的自动化变量,可以极大地方便我们编写 Makefile,让我们更容易写出一些规则的“模板”。 另外,准确说来自动化变量的名称是不包括前面的那个 $ 号的,那不过表示对这个自动化变量进行求值,所以下表也没列出(这也意味着 $@$(@) 是等效的)。

自动化变量 意义
@ 目标集合
% 仅当目标是函数库文件(UNIX下的 .a 文件,Windows下的 .lib 文件)时,其值为依赖文件,否则为空
< 依赖目标中的第一个目标
? 所有比目标新的依赖目标的集合,以空格分隔
^ 所有依赖目标的集合(去重),以空格分隔
+ 所有依赖目标的集合(不去重),以空格分隔

接下来就是各种各样的隐含规则了。

%.o: %.c
        $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $?

%.o: %.C
        $(CXX) $(CFLAGS) $(CPPFLAGS) -c -o $@ $?

%.o: %.CC
        $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -o $@ $?

%.o: %.p
        $(PC) -c $(PFLAGS) $? -o $@

%.o: %.f
        $(FC) -c $(FFLAGS) $? -o $@

%.f: %.F
        $(FC) -F $(CPPFLAGS) $(FFLAGS) $? -o $@

%.f: %.r
        $(FC) -F $(FFLAGS) $(RFLAGS) $? -o $@

%.o: %.F
        $(FC) -c $(FFLAGS) $(CPPFLAGS) $? -o $@

%.o: %.r
        $(FC) -c $(FFLAGS) $(RFLAGS) $? -o $@

%.sym: %.def
        $(M2C) $(M2FLAGS) $(DEFFLAGS) $? -o $@

%.o: %.mod
        $(M2C) $(M2FLAGS) $(MODFLAGS) $? -o $@

%.o: %.s
        $(AS) $(ASFLAGS) $? -o $@

%.s: %.S
        $(CC) -E $(CPPFLAGS) $? > $@

%: %.o
        $(CC) $(LDFLAGS) $? $(LOADLIBES) $(LDLIBS) -o $@

%.c: %.y
        $(YACC) $(YFLAGS) $?
        mv -f y.tab.c %@

%.c: %.l
        $(LEX) $(LFLAGS) -t $? > $@

最后再说一个小技巧,如果某目标依赖某文件,但在编译该目标的时候又不需要编译器编译该依赖文件(比如某目标 foo.o 依赖 bar.h ,但是编译 foo.o 的时候其实是不用将 bar.h 写到编译命令里的,但如果不在依赖关系里写出的话,更新了 bar.h 又不能 make 时自行重新编译 foo.c ),可以考虑这么做:

foo.o: foo.c bar.h
        $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $(*F).c